package com.xwj.exception.solution_2.handler;

import com.google.common.base.Stopwatch;
import com.google.common.collect.Lists;
import com.xwj.common.util.R;
import com.xwj.exception.common.exceptions.BusinessException;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;

import java.util.concurrent.TimeUnit;

/**
 * @Author: xiaowajiang
 * @Date: 2022-04-06 20:53
 * @Description: 基于AOP的全局异常统一处理
 **/
@Slf4j
@Component
@Aspect
public class AspectException {

    @Pointcut("execution(* com.xwj.exception.solution_2.demo.controller.*.*(..))") // 切入点
    public void pointCut(){}

    @Around("pointCut()")
    public R handleControllerMethod(ProceedingJoinPoint pjp) {
        Stopwatch stopwatch = Stopwatch.createStarted();
        R r;
        try {
            log.info("执行Controller开始: " + pjp.getSignature() + " 参数：" + Lists.newArrayList(pjp.getArgs()).toString());
            r = (R) pjp.proceed(pjp.getArgs());
            log.info("执行Controller结束: " + pjp.getSignature() + "， 返回值：" + r.toString());
            log.info("耗时：" + stopwatch.stop().elapsed(TimeUnit.MILLISECONDS) + "(毫秒).");
        } catch (Throwable throwable) {
            r = handlerException(pjp, throwable);
        }
        return r;
    }

    /**
     * 处理异常信息
     * @param pjp
     * @param e
     * @return
     */
    private R handlerException(ProceedingJoinPoint pjp, Throwable e) {
        R r = null;
        if (e instanceof BusinessException) {
            BusinessException businessException = (BusinessException) e;
            log.error("BusinessException{方法：" + pjp.getSignature() + "， 参数：" + pjp.getArgs() + ",异常：" + businessException.getMessage() + "}", e);
            r = R.error(businessException.getCode(), businessException.getMessage());
        } else if (e instanceof RuntimeException) {
            log.error("RuntimeException{方法：" + pjp.getSignature() + "， 参数：" + pjp.getArgs() + ",异常：" + e.getMessage() + "}", e);
            r = R.error("9999", "未知异常");
        } else {
            log.error("异常{方法：" + pjp.getSignature() + "， 参数：" + pjp.getArgs() + ",异常：" + e.getMessage() + "}", e);
            r = R.error("500", "系统异常");
        }
        return r;
    }
}
